package main.fileiterators;

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import data.ConfigurationGraphData;
import data.ConfigurationGraphObject;
import data.Saver;

public class ImprovementCounter implements SaverPerformer {

	Map<ConfigurationGraphObject, ConfigurationGraphObject> m;

	public ImprovementCounter() {
		m = new HashMap<ConfigurationGraphObject, ConfigurationGraphObject>();
	}

	@Override
	public void doWithSaver(Saver s) {
		ConfigurationGraphData d = s.loadConfiguration(1);
		if (d.get_ppp().size()>1){
			ConfigurationGraphObject allScsi = null;
			for (ConfigurationGraphObject conf: d.get_ppp()){
				if (conf.get_amountSATA()==0 && conf.get_amountSSD()==0 && conf.get_amountSCSI() > 0){
					allScsi = conf;
					break;
				}
			}
			double min = Double.MAX_VALUE;
			ConfigurationGraphObject minConf = null;
			for (ConfigurationGraphObject conf: d.get_ppp()){
				double res = conf.get_price()/allScsi.get_price() + conf.get_performance()/allScsi.get_performance() + conf.get_powerConsumption()/allScsi.get_powerConsumption();
				res = res/3.0;
				if (res < min){
					min = res;
					minConf = conf;
				}
			}
			m.put(minConf, allScsi);
		}
	}

	@Override
	public String printResults() {
		Vector<ConfigurationGraphObject> res = new Vector<ConfigurationGraphObject>();
		for (ConfigurationGraphObject conf: m.keySet()){
			res.add(conf);
		}
		Collections.sort(res, new Comparator<ConfigurationGraphObject>(){
			@Override
			public int compare(ConfigurationGraphObject o1, ConfigurationGraphObject o2) {
				double o1perf = o1.get_performance()/m.get(o1).get_performance();
				double o2perf = o2.get_performance()/m.get(o2).get_performance();
				double o1pric = o1.get_price()/m.get(o1).get_price();
				double o2pric = o2.get_price()/m.get(o2).get_price();
				double o1ener = o1.get_powerConsumption()/m.get(o1).get_powerConsumption();
				double o2ener = o2.get_powerConsumption()/m.get(o2).get_powerConsumption();
				if (o1perf < o2perf){
					return -1;
				} else if (o2perf < o1perf){
					return 1;
				} else if (o1ener < o2ener){
					return -1;
				} else if (o2ener < o1ener){
					return 1;
				} else if (o1pric < o2pric){
					return -1;
				} else if (o2pric < o1pric){
					return 1;
				} else {
					return 0;
				}
			}
		});

		String ans = "";

		for (ConfigurationGraphObject o1 : res){
			double o1perf = o1.get_performance()/m.get(o1).get_performance();
			double o1pric = o1.get_price()/m.get(o1).get_price();
			double o1ener = o1.get_powerConsumption()/m.get(o1).get_powerConsumption();
			ans = ans + o1perf + "\t" + o1pric + "\t" + o1ener + "\n";
		}
		
//		Collections.sort(res, new Comparator<ConfigurationGraphObject>(){
//			@Override
//			public int compare(ConfigurationGraphObject o1, ConfigurationGraphObject o2) {
//				double o1total = o1.get_amountSATA() + o1.get_amountSCSI() + o1.get_amountSSD(); 
//				double o1SATA = o1.get_amountSATA()/o1total;
//				double o1SCSI = o1.get_amountSCSI()/o1total;
//				double o1SSD = o1.get_amountSSD()/o1total;
//				double o2total = o2.get_amountSATA() + o2.get_amountSCSI() + o2.get_amountSSD(); 
//				double o2SATA = o2.get_amountSATA()/o2total;
//				double o2SCSI = o2.get_amountSCSI()/o2total;
//				double o2SSD = o2.get_amountSSD()/o2total;
//				
//				if (o1SATA < o2SATA){
//					return -1;
//				} else if (o2SATA < o1SATA){
//					return 1;
//				} else if (o1SCSI < o2SCSI){
//					return -1;
//				} else if (o2SCSI < o1SCSI){
//					return 1;
//				} else if (o1SSD < o2SSD){
//					return -1;
//				} else if (o2SSD < o1SSD){
//					return 1;
//				} else {
//					return 0;
//				}
//			}
//		});
		
		ans+= "\n\n\n\n\n\n";
		for (ConfigurationGraphObject o1 : res){
			double total = o1.get_amountSATA() + o1.get_amountSCSI() + o1.get_amountSSD(); 
			double o1SATA = o1.get_amountSATA()/total;
			double o1SCSI = o1.get_amountSCSI()/total;
			double o1SSD = o1.get_amountSSD()/total;
			
			ans = ans + o1SATA + "\t" + o1SCSI + "\t" + o1SSD + "\n";
		}
		
		return ans;
	}
}
